home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 43 / Amiga Format CD43 (1999)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1999-09].iso / -serious- / comms / other / ascan / sources / ascan.c < prev    next >
C/C++ Source or Header  |  1999-06-14  |  5KB  |  207 lines

  1.  
  2. #include "ascan.h"
  3. #include <bsdsocket/socketbasetags.h>
  4. #include <sys/ioctl.h>
  5.  
  6. /***************************************************************************/
  7.  
  8. /*This is called as a stand alone process*/
  9. /*"Real programmer blah blah blah" - I love "goto" and I use it :) */
  10.  
  11. void SAVEDS ascan(void)
  12. {
  13.     register char                buf[256];
  14.     register int                 socks[MAX_SOCKS_PER_TASK], n;
  15.     register struct childMsg     *msg;
  16.     register struct Process     *me;
  17.     register struct DosLibrary    *DOSBase;
  18.     register struct Library     *SocketBase=NULL;
  19.     struct sockaddr_in             sin;
  20.     register BPTR                out;
  21.     register ULONG                res = 0, srec, flags, t, sig, ppt;
  22.     register int                 i, j, from, to, stop, sock, err, bad, l;
  23.     ULONG                        value;
  24.     fd_set                        read;
  25.  
  26.     /*here we go*/
  27.     me = (struct Process *)FindTask(NULL);
  28.     msg = (struct childMsg *)WaitPort(&me->pr_MsgPort);
  29.     Remove(NODE(msg));
  30.  
  31.     /*let's open whatever we need*/
  32.     if (!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",0)))
  33.     {
  34.         res = SCAN_ERROR_NOMEM;
  35.         goto end;
  36.     }
  37.  
  38.     if (!(SocketBase = OpenLibrary("bsdsocket.library",0)))
  39.     {
  40.         res = SCAN_ERROR_NOBSDSOCKET;
  41.         goto end;
  42.     }
  43.  
  44.     /* local copy of some stuff from the startup msg*/
  45.     out   = Output();
  46.     from  = msg->from;
  47.     to    = msg->to;
  48.     flags = msg->g->flags;
  49.     ppt   = msg->g->ppt;
  50.  
  51.     sin.sin_addr.s_addr = msg->host;
  52.     sin.sin_family      = AF_INET;
  53.     sin.sin_len         = sizeof(struct sockaddr_in);
  54.  
  55.     /*we need it for async sockets*/
  56.     sig=AllocSignal(-1);
  57.  
  58.     /*now we set the socket table size and the async sockets signal*/
  59.     SocketBaseTags(SBTM_SETVAL(SBTC_DTABLESIZE),   ppt,
  60.                    SBTM_SETVAL(SBTC_SIGEVENTMASK), 1<<sig,
  61.                    TAG_DONE);
  62.  
  63.     /*n cycle for ppt sockets*/
  64.     t = to-from+1;
  65.     n = t/ppt;
  66.     if (t%ppt) n++;
  67.  
  68.     for (j=0; !res && (j<n); j++, from+=ppt)
  69.     {
  70.         FD_ZERO(&read);
  71.  
  72.         t = ((from+ppt)>to)? to : from+ppt-1;
  73.         stop=t-from+1;
  74.  
  75.         bad=0;
  76.         for (i = from; i<=t; i++)
  77.         {
  78.             /*if we got a ctrl_c we exit*/
  79.             if (SetSignal(0,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
  80.             {
  81.                 res = SCAN_ERROR_BREAK;
  82.                 goto end;
  83.             }
  84.  
  85.             if ((sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0)
  86.             {
  87.                 res = SCAN_ERROR_NOSOCKET;
  88.                 goto end;
  89.             }
  90.  
  91.             /*we just wait for a connect event ...*/
  92.             value = FD_CONNECT;
  93.             setsockopt(sock,SOL_SOCKET,SO_EVENTMASK,&value,sizeof(value));
  94.  
  95.             /*...in async way, but if we get an error right now we catch it*/
  96.             *(socks+sock) = sin.sin_port = i;
  97.             if ((connect(sock,(struct sockaddr *)&sin,sizeof(sin))<0) &&
  98.                 ((err=Errno())!=35) && (err!=36))
  99.             {
  100.                 bad++;
  101.                 CloseSocket(sock);
  102.             }
  103.             else FD_SET(sock,&read);
  104.  
  105.             /*while creating socket, we can catch async events as well*/
  106.             if (SetSignal(0,(1<<sig)) & (1<<sig))
  107.             {
  108.                 while ((sock=GetSocketEvents(&value))>=0)
  109.                 {
  110.                     stop--;
  111.                     FD_CLR(sock,&read);
  112.                     if (value & FD_CONNECT)
  113.                     {
  114.                         register struct servent    *se;
  115.  
  116.                         if ((flags & FLG_PORTNAME) && (se = getservbyport(*(socks+sock),"tcp")))
  117.                             l=sprintf(buf,"%s (%ld)\n",se->s_name,*(socks+sock));
  118.                         else l=sprintf(buf,"%ld\n",*(socks+sock));
  119.                         Write(out,buf,l);
  120.                     }
  121.                     CloseSocket(sock);
  122.                 }
  123.             }
  124.  
  125.             /*if we got a ctrl_d we output infos*/
  126.             if (SetSignal(0,SIGBREAKF_CTRL_D) & SIGBREAKF_CTRL_D)
  127.             {
  128.                 l=sprintf(buf,"%s: port %ld/%ld of cycle %ld/%ld\n",msg->name,i-from+1,t-from+1,j+1,n);
  129.                 Write(out,buf,l);
  130.             }
  131.         }
  132.  
  133.         /*if the error was too big :)*/
  134.         if (bad==stop)
  135.         {
  136.             if (err!=61) res=SCAN_ERROR_SENDING;
  137.             goto end;
  138.         }
  139.  
  140.         /* we must wait for "stop" sockets to go*/
  141.         stop=stop-bad;
  142.         while (stop)
  143.         {
  144.             srec = Wait((1<<sig) | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D);
  145.  
  146.             if (srec & SIGBREAKF_CTRL_C)
  147.             {
  148.                 res = SCAN_ERROR_BREAK;
  149.                 goto end;
  150.             }
  151.  
  152.             if (srec & (1<<sig))
  153.             {
  154.                 while ((sock=GetSocketEvents(&value))>=0)
  155.                 {
  156.                     stop--;
  157.                     FD_CLR(sock,&read);
  158.                     if (value & FD_CONNECT)
  159.                     {
  160.                         register struct servent    *se;
  161.  
  162.                         if ((flags & FLG_PORTNAME) && (se = getservbyport(*(socks+sock),"tcp")))
  163.                             l=sprintf(buf,"%s (%ld)\n",se->s_name,*(socks+sock));
  164.                         else l=sprintf(buf,"%ld\n",*(socks+sock));
  165.                         Write(out,buf,l);
  166.                     }
  167.                     CloseSocket(sock);
  168.                 }
  169.             }
  170.  
  171.             if (srec & SIGBREAKF_CTRL_D)
  172.             {
  173.                 l=sprintf(buf,"%s: ports to wait %ld/%ld of cycle %ld/%ld\n",msg->name,stop,t-from+1,j+1,n);
  174.                 Write(out,buf,l);
  175.             }
  176.         }
  177.     }
  178.  
  179. end:
  180.     if (DOSBase)
  181.     {
  182.         if (SocketBase)
  183.         {
  184.             if (res) msg->code = Errno();
  185.             if (!(flags & FLG_LIMITED))
  186.             {
  187.                 /*closing SocketBase would do that but...*/
  188.                 for (i = from; i<=to; i++)
  189.                 {
  190.                     sock = i-from;
  191.                     if (FD_ISSET(sock,&read)) CloseSocket(sock);
  192.                 }
  193.                 FreeSignal(sig);
  194.             }
  195.             CloseLibrary(SocketBase);
  196.         }
  197.         CloseLibrary((struct Library *)DOSBase);
  198.     }
  199.     /*report the result, Forbid() so nobody can flush us, and exit*/
  200.     msg->res = res;
  201.     Forbid();
  202.     *(msg->g->childs+msg->tnum) = NULL;
  203.     ReplyMsg((struct Message *)msg);
  204. }
  205.  
  206. /***************************************************************************/
  207.